/*

TiMidity -- Experimental MIDI to WAVE converter
Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

instrum.c

Code to load and unload GUS-compatible instrument patches.

*/

#include <stdio.h>

#ifndef _WIN32_WCE
#include <string.h>
#endif

#if defined(__FreeBSD__) || defined (__WIN32__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif

#include "config.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "output.h"
#include "resample.h"
#include "tables.h"
#include "filter.h"

/* Some functions get aggravated if not even the standard banks are
available. */
static ToneBank standard_tonebank, standard_drumset;
ToneBank
*tonebank[128]={&standard_tonebank},
*drumset[128]={&standard_drumset};

/* This is a special instrument, used for all melodic programs */
Instrument *default_instrument=0;

/* This is only used for tracks that don't specify a program */
int default_program=DEFAULT_PROGRAM;

int antialiasing_allowed=0;
#ifdef FAST_DECAY
int fast_decay=1;
#else
int fast_decay=0;
#endif

static void free_instrument(Instrument *ip)
{
    Sample *sp;
    int i;
    if (!ip) return;
    for (i=0; i<ip->samples; i++)
    {
        sp=&(ip->sample[i]);
        free(sp->data);
    }
    free(ip->sample);
    free(ip);
}

static void free_bank(int dr, int b)
{
    int i;
    ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
    for (i=0; i<128; i++)
    if (bank->tone[i].instrument)
    {
        /* Not that this could ever happen, of course */
        if (bank->tone[i].instrument != MAGIC_LOAD_INSTRUMENT)
        free_instrument(bank->tone[i].instrument);
        bank->tone[i].instrument=0;
    }
}

static int32 convert_envelope_rate(uint8 rate)
{
    int32 r;
    
    r=3-((rate>>6) & 0x3);
    r*=3;
    r = (int32)(rate & 0x3f) << r; /* 6.9 fixed point */
    
    /* 15.15 fixed point. */
    return (((r * 44100) / play_mode->rate) * control_ratio)
    << ((fast_decay) ? 10 : 9);
}

static int32 convert_envelope_offset(uint8 offset)
{
    /* This is not too good... Can anyone tell me what these values mean?
    Are they GUS-style "exponential" volumes? And what does that mean? */
    
    /* 15.15 fixed point */
    return offset << (7+15);
}

static int32 convert_tremolo_sweep(uint8 sweep)
{
    if (!sweep)
    return 0;
    
    return
    ((control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
    (play_mode->rate * sweep);
}

static int32 convert_vibrato_sweep(uint8 sweep, int32 vib_control_ratio)
{
    if (!sweep)
    return 0;
    
    return
    (int32) (FSCALE((double) (vib_control_ratio) * SWEEP_TUNING, SWEEP_SHIFT)
    / (double)(play_mode->rate * sweep));
    
    /* this was overflowing with seashore.pat
    
    ((vib_control_ratio * SWEEP_TUNING) << SWEEP_SHIFT) /
    (play_mode->rate * sweep); */
}

static int32 convert_tremolo_rate(uint8 rate)
{
    return
    ((SINE_CYCLE_LENGTH * control_ratio * rate) << RATE_SHIFT) /
    (TREMOLO_RATE_TUNING * play_mode->rate);
}

static int32 convert_vibrato_rate(uint8 rate)
{
    /* Return a suitable vibrato_control_ratio value */
    return
    (VIBRATO_RATE_TUNING * play_mode->rate) /
    (rate * 2 * VIBRATO_SAMPLE_INCREMENTS);
}

static void reverse_data(int16 *sp, int32 ls, int32 le)
{
    int16 s, *ep=sp+le;
    sp+=ls;
    le-=ls;
    le/=2;
    while (le--)
    {
        s=*sp;
        *sp++=*ep;
        *ep--=s;
    }
}

/*
If panning or note_to_use != -1, it will be used for all samples,
instead of the sample-specific values in the instrument file.

For note_to_use, any value <0 or >127 will be forced to 0.

For other parameters, 1 means yes, 0 means no, other values are
undefined.

TODO: do reverse loops right */
static Instrument *load_instrument(char *name, int percussion,
int panning, int amp, int note_to_use,
int strip_loop, int strip_envelope,
int strip_tail)
{
    Instrument *ip;
    Sample *sp;
    FILE *fp;
    uint8 tmp[1024];
    int i,j,noluck=0;
#ifdef PATCH_EXT_LIST
    static char *patch_ext[] = PATCH_EXT_LIST;
#endif
    
    if (!name) return 0;
    
    /* Open patch file */
    if (!(fp=open_file(name, 1, OF_NORMAL)))
    {
        noluck=1;
#ifdef PATCH_EXT_LIST
        /* Try with various extensions */
        for (i=0; patch_ext[i]; i++)
        {
            if (strlen(name)+strlen(patch_ext[i])<1024)
            {
                strcpy(tmp, name);
                strcat(tmp, patch_ext[i]);
                if ((fp=open_file(tmp, 1, OF_NORMAL)))
                {
                    noluck=0;
                    break;
                }
            }
        }
#endif
    }
    
    if (noluck)
    {
        return 0;
    }
        
    /* Read some headers and do cursory sanity checks. There are loads
    of magic offsets. This could be rewritten... */
    
    if ((239 != fread(tmp, 1, 239, fp)) ||
    (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) &&
    memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the
    differences are */
    {
        return 0;
    }
    
    if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers,
    0 means 1 */
    {
        return 0;
    }
    
    if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */
    {
        return 0;
    }
    
    ip=safe_malloc(sizeof(Instrument));
    ip->samples = tmp[198];
    ip->sample = safe_malloc(sizeof(Sample) * ip->samples);
    for (i=0; i<ip->samples; i++)
    {
        
        uint8 fractions;
        int32 tmplong;
        uint16 tmpshort;
        uint8 tmpchar;
        
#define READ_CHAR(thing) \
        if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \
        thing = tmpchar;
#define READ_SHORT(thing) \
        if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \
        thing = LE_SHORT(tmpshort);
#define READ_LONG(thing) \
        if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \
        thing = LE_LONG(tmplong);
        
        skip(fp, 7); /* Skip the wave name */
        
        if (1 != fread(&fractions, 1, 1, fp))
        {
            fail:
            for (j=0; j<i; j++)
				free(ip->sample[j].data);
            free(ip->sample);
            free(ip);
            return 0;
        }
        
        sp=&(ip->sample[i]);
        
        READ_LONG(sp->data_length);
        READ_LONG(sp->loop_start);
        READ_LONG(sp->loop_end);
        READ_SHORT(sp->sample_rate);
        READ_LONG(sp->low_freq);
        READ_LONG(sp->high_freq);
        READ_LONG(sp->root_freq);
        skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */
        
        READ_CHAR(tmp[0]);
        
        if (panning==-1)
        sp->panning = (tmp[0] * 8 + 4) & 0x7f;
        else
        sp->panning=(uint8)(panning & 0x7F);
        
        /* envelope, tremolo, and vibrato */
        if (18 != fread(tmp, 1, 18, fp)) goto fail;
        
        if (!tmp[13] || !tmp[14])
        {
            sp->tremolo_sweep_increment=
            sp->tremolo_phase_increment=sp->tremolo_depth=0;
        }
        else
        {
            sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]);
            sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]);
            sp->tremolo_depth=tmp[14];
        }
        
        if (!tmp[16] || !tmp[17])
        {
            sp->vibrato_sweep_increment=
            sp->vibrato_control_ratio=sp->vibrato_depth=0;
        }
        else
        {
            sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]);
            sp->vibrato_sweep_increment=
            convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio);
            sp->vibrato_depth=tmp[17];            
        }
        
        READ_CHAR(sp->modes);
        
        skip(fp, 40); /* skip the useless scale frequency, scale factor
        (what's it mean?), and reserved space */
        
        /* Mark this as a fixed-pitch instrument if such a deed is desired. */
        if (note_to_use!=-1)
        sp->note_to_use=(uint8)(note_to_use);
        else
        sp->note_to_use=0;
        
        /* seashore.pat in the Midia patch set has no Sustain. I don't
        understand why, and fixing it by adding the Sustain flag to
        all looped patches probably breaks something else. We do it
        anyway. */
        
        if (sp->modes & MODES_LOOPING)
        sp->modes |= MODES_SUSTAIN;
        
        /* Strip any loops and envelopes we're permitted to */
        if ((strip_loop==1) &&
        (sp->modes & (MODES_SUSTAIN | MODES_LOOPING |
        MODES_PINGPONG | MODES_REVERSE)))
        {
            sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE);
        }
        
        if (strip_envelope==1)
        {
            sp->modes &= ~MODES_ENVELOPE;
        }
        else if (strip_envelope != 0)
        {
            /* Have to make a guess. */
            if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE)))
            {
                /* No loop? Then what's there to sustain? No envelope needed
                either... */
                sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE);
            }
            else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100)
            {
                /* Envelope rates all maxed out? Envelope end at a high "offset"?
                That's a weird envelope. Take it out. */
                sp->modes &= ~MODES_ENVELOPE;
            }
            else if (!(sp->modes & MODES_SUSTAIN))
            {
                /* No sustain? Then no envelope.  I don't know if this is
                justified, but patches without sustain usually don't need the
                envelope either... at least the Gravis ones. They're mostly
                drums.  I think. */
                sp->modes &= ~MODES_ENVELOPE;
            }
        }
        
        for (j=0; j<6; j++)
        {
            sp->envelope_rate[j]=
            convert_envelope_rate(tmp[j]);
            sp->envelope_offset[j]=
            convert_envelope_offset(tmp[6+j]);
        }
        
        /* Then read the sample data */
        sp->data = safe_malloc(sp->data_length);
        if (1 != fread(sp->data, sp->data_length, 1, fp))
        goto fail;
        
        if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */
        {
            int32 i=sp->data_length;
            uint8 *cp=(uint8 *)(sp->data);
            uint16 *tmp,*new;
            tmp=new=safe_malloc(sp->data_length*2);
            while (i--)
            *tmp++ = (uint16)(*cp++) << 8;
            cp=(uint8 *)(sp->data);
            sp->data = (sample_t *)new;
            free(cp);
            sp->data_length *= 2;
            sp->loop_start *= 2;
            sp->loop_end *= 2;
        }
#ifndef LITTLE_ENDIAN
        else
        /* convert to machine byte order */
        {
            int32 i=sp->data_length/2;
            int16 *tmp=(int16 *)sp->data,s;
            while (i--)
            {
                s=LE_SHORT(*tmp);
                *tmp++=s;
            }
        }
#endif
        
        if (sp->modes & MODES_UNSIGNED) /* convert to signed data */
        {
            int32 i=sp->data_length/2;
            int16 *tmp=(int16 *)sp->data;
            while (i--)
            *tmp++ ^= 0x8000;
        }
        
        /* Reverse reverse loops and pass them off as normal loops */
        if (sp->modes & MODES_REVERSE)
        {
            int32 t;
            /* The GUS apparently plays reverse loops by reversing the
            whole sample. We do the same because the GUS does not SUCK. */
            reverse_data((int16 *)sp->data, 0, sp->data_length/2);
            
            t=sp->loop_start;
            sp->loop_start=sp->data_length - sp->loop_end;
            sp->loop_end=sp->data_length - t;
            
            sp->modes &= ~MODES_REVERSE;
            sp->modes |= MODES_LOOPING; /* just in case */
        }
        
        /* If necessary do some anti-aliasing filtering  */
        
        if (antialiasing_allowed)
        antialiasing(sp,play_mode->rate);
        
#ifdef ADJUST_SAMPLE_VOLUMES
        if (amp!=-1)
        sp->volume=(double)(amp) / 100.0;
        else
        {
            /* Try to determine a volume scaling factor for the sample.
            This is a very crude adjustment, but things sound more
            balanced with it. Still, this should be a runtime option. */
            int32 i=sp->data_length/2;
            int16 maxamp=0,a;
            int16 *tmp=(int16 *)sp->data;
            while (i--)
            {
                a=*tmp++;
                if (a<0) a=-a;
                if (a>maxamp)
                maxamp=a;
            }
            sp->volume=32768.0 / (double)(maxamp);
        }
#else
        if (amp!=-1)
        sp->volume=(double)(amp) / 100.0;
        else
        sp->volume=1.0;
#endif
        
        sp->data_length /= 2; /* These are in bytes. Convert into samples. */
        sp->loop_start /= 2;
        sp->loop_end /= 2;
        
        /* Then fractional samples */
        sp->data_length <<= FRACTION_BITS;
        sp->loop_start <<= FRACTION_BITS;
        sp->loop_end <<= FRACTION_BITS;
        
        /* Adjust for fractional loop points. This is a guess. Does anyone
        know what "fractions" really stands for? */
        sp->loop_start |=
        (fractions & 0x0F) << (FRACTION_BITS-4);
        sp->loop_end |=
        ((fractions>>4) & 0x0F) << (FRACTION_BITS-4);
        
        /* If this instrument will always be played on the same note,
        and it's not looped, we can resample it now. */
        if (sp->note_to_use && !(sp->modes & MODES_LOOPING))
        pre_resample(sp);
        
#ifdef LOOKUP_HACK
        /* Squash the 16-bit data into 8 bits. */
        {
            uint8 *gulp,*ulp;
            int16 *swp;
            int l=sp->data_length >> FRACTION_BITS;
            gulp=ulp=safe_malloc(l+1);
            swp=(int16 *)sp->data;
            while(l--)
            *ulp++ = (*swp++ >> 8) & 0xFF;
            free(sp->data);
            sp->data=(sample_t *)gulp;
        }
#endif
        
        if (strip_tail==1)
        {
            /* Let's not really, just say we did. */
            sp->data_length = sp->loop_end;
        }
    }
    
    close_file(fp);
    return ip;
}

static int fill_bank(int dr, int b)
{
    int i, errors=0;
    ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);
    if (!bank)
    {
        return 0;
    }
    for (i=0; i<128; i++)
    {
        if (bank->tone[i].instrument==MAGIC_LOAD_INSTRUMENT)
        {
            if (!(bank->tone[i].name))
            {
                if (b!=0)
                {
                    /* Mark the corresponding instrument in the default
                    bank / drumset for loading (if it isn't already) */
                    if (!dr)
                    {
                        if (!(standard_tonebank.tone[i].instrument))
                        standard_tonebank.tone[i].instrument=
                        MAGIC_LOAD_INSTRUMENT;
                    }
                    else
                    {
                        if (!(standard_drumset.tone[i].instrument))
                        standard_drumset.tone[i].instrument=
                        MAGIC_LOAD_INSTRUMENT;
                    }
                }
                bank->tone[i].instrument=0;
                errors++;
            }
            else if (!(bank->tone[i].instrument=
            load_instrument(bank->tone[i].name,
            (dr) ? 1 : 0,
            bank->tone[i].pan,
            bank->tone[i].amp,
            (bank->tone[i].note!=-1) ?
            bank->tone[i].note :
            ((dr) ? i : -1),
            (bank->tone[i].strip_loop!=-1) ?
            bank->tone[i].strip_loop :
            ((dr) ? 1 : -1),
            (bank->tone[i].strip_envelope != -1) ?
            bank->tone[i].strip_envelope :
            ((dr) ? 1 : -1),
            bank->tone[i].strip_tail )))
            {
                errors++;
            }
        }
    }
    return errors;
}

#if 0
// original
int load_missing_instruments(void)
{
    int i=128,errors=0;
    while (i--)
    {
        if (tonebank[i])
        errors+=fill_bank(0,i);
        if (drumset[i])
        errors+=fill_bank(1,i);
    }
    return errors;
}
#else

int load_instruments = 0;
int load_errors = 0;

void start_load_missing_instruments(void)
{
	load_instruments = 127;
	load_errors = 0;
}

int load_missing_instruments(void)
{
	if (load_instruments >= 0) {
		if (tonebank[load_instruments])
			load_errors += fill_bank(0, load_instruments);
		if (drumset[load_instruments])
			load_errors += fill_bank(1, load_instruments);

		load_instruments--;
		return 1;
	}
	return 0;
}
#endif

void free_instruments(void)
{
	int i=128;

	while (i--) 
	{
        if (tonebank[i])
		    free_bank(0, i);
        if (drumset[i])
			free_bank(1, i);
    }
}

int set_default_instrument(char *name)
{
    Instrument *ip;
    if (!(ip=load_instrument(name, 0, -1, -1, -1, 0, 0, 0)))
    return -1;
    if (default_instrument)
    free_instrument(default_instrument);
default_instrument=ip;
default_program=SPECIAL_PROGRAM;
    return 0;
}
